package com.love.marriage.cloud.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baidubce.http.ApiExplorerClient;
import com.baidubce.http.AppSigner;
import com.baidubce.http.HttpMethodName;
import com.baidubce.model.ApiExplorerRequest;
import com.baidubce.model.ApiExplorerResponse;
import com.love.marriage.cloud.service.BaiduyunService;
import com.love.marriage.common.redisKey.IpKey;
import com.love.marriage.config.BaiducloudConfig;
import com.love.marriage.regionInfo.service.RegionInfoService;
import com.love.marriage.regionInfo.vo.RegionDetailInfoVo;
import com.love.marriage.utils.IpUtils;
import com.love.marriage.utils.RedisUtils;
import com.love.marriage.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
@Slf4j
public class BaiduyunServiceImpl implements BaiduyunService {

    private final BaiducloudConfig baiducloudConfig;

    private final RegionInfoService regionInfoService;

    private final RedisUtils redisUtils;

    @Override
    public Map<String, Object> ip2address(HttpServletRequest request, String ip) throws Exception {
        if (ip == null || ip.isEmpty()) {
            ip = IpUtils.getIpAddr(request);
            log.info("ip为空，使用本机ip:{}", ip);
        }
        String ipInfo = redisUtils.get(IpKey.ipKey.getPrefix() + ":" + ip);
        if (StringUtils.isNotBlank(ipInfo)) {
            log.info("redis ip缓存：{}", ipInfo);
            return JSONObject.parseObject(ipInfo, Map.class);
        }
        ApiExplorerRequest requestInfo = new ApiExplorerRequest(HttpMethodName.GET, baiducloudConfig.getUrl());
        requestInfo.setCredentials(baiducloudConfig.getAccessKey(), baiducloudConfig.getSecretKey());
        // 设置header参数
        requestInfo.addHeaderParameter("Content-Type", "application/json; charset=utf-8");
        // 设置query参数
        requestInfo.addQueryParameter("ip", ip);
        ApiExplorerClient client = new ApiExplorerClient(new AppSigner());
        Map<String, Object> res = new HashMap<>();
        log.info("请求百度云API服务，查询IP地址：{},请求参数：{}", ip, requestInfo);
        ApiExplorerResponse response = client.sendRequest(requestInfo);
        //  返回结果格式为Json字符串
        log.info("请求百度云API服务，查询IP地址：{},返回结果：{}", ip, response.getResult());
        Map map = JSONObject.parseObject(response.getResult(), new TypeReference<Map<String, Object>>() {
        });
        if (map == null || !map.containsKey("status") || !"0".equals(map.get("status").toString())) {
            log.warn("Invalid response or status is not '0'");
            throw new Exception("Invalid response or status is not '0'");
        }
        // Retrieve ad_info map and validate
        Map<String, Object> result = (Map<String, Object>) map.get("result");
        Map<String, Object> adInfo = (Map<String, Object>) result.get("ad_info");
        if (adInfo == null) {
            log.warn("ad_info is missing in the response");
            throw new Exception("ad_info is missing in the response");
        }
        // Extract province, city, and district with null safety
        String province = (String) adInfo.getOrDefault("province", "");
        String city = (String) adInfo.getOrDefault("city", "");
        String district = (String) adInfo.getOrDefault("district", "");
        // Populate response map
        res.put("province", province);
        res.put("city", city);
        res.put("district", district);
        // Get detailed region info
        RegionDetailInfoVo regionDetailInfoVo = regionInfoService.reginDetailInfo(province, city, district);
        if (regionDetailInfoVo != null) {
            res.put("districtId", regionDetailInfoVo.getDistrictId());
            res.put("cityId", regionDetailInfoVo.getCityId());
            res.put("provinceId", regionDetailInfoVo.getProvinceId());
        }
        redisUtils.setEx(IpKey.ipKey, ip, JSONObject.toJSONString(res), 60 * 60 * 24 * 7, TimeUnit.SECONDS);
        return res;
    }
}
